// Copyright (c) 2011 Vratislav Cermak (vratacermak@gmail.com)
//  
// This file is part of SrtSync Project. See http://code.google.com/p/srtsync/ for more information.
//  
// SrtSync is an open source project. Using of SrtSync is free of charge.
// It is distributed under GNU General Public License version 3 (GPLv3).
// GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
//  
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the license for more details.

using System;
using System.Collections.Generic;
using System.Linq;
using SrtSync.Core.Framework;
using SrtSync.Core.Notifications;

namespace SrtSync.Core.Data
{
    public class Editor : Observable<EditorModelNotification>, IEditor
    {
        private readonly SrtReader _reader = new SrtReader();
        private bool _modified;

        public string Path { get; set; }

        public void Load(string path)
        {
            try
            {
                _reader.Load(path, Encoding);
            }
            catch (Exception)
            {
                Close();
                
                throw;
            }

            Path = path;
            Modified = false;
            
            Notify(new EditorModelNotification {Type = EditorModelNotificationTypes.Reload});
        }

        public void Save()
        {
            SrtWriter writer = new SrtWriter();
            writer.Save(Path, Encoding, Entries);
            Modified = false;
        }

        public void SaveAs(string path)
        {
            SrtWriter writer = new SrtWriter();
            writer.Save(path, Encoding, Entries);
            Path = path;
            Modified = false;
        }

        public void SaveCopy(string path)
        {
            SrtWriter writer = new SrtWriter();
            writer.Save(path, Encoding, Entries);
        }

        public void Close()
        {
            _reader.Clear();
            Modified = false;
            
            Notify(new EditorModelNotification { Type = EditorModelNotificationTypes.Reload });
        }

        public void Delete(IEnumerable<Entry> entries)
        {
            _reader.Delete(entries);
            Modified = true;

            Notify(new EditorModelNotification { Type = EditorModelNotificationTypes.Remove, Entries = entries });
            
        }

        public void Merge(IEnumerable<Entry> entries)
        {
            Entry mergedEntry = _reader.Merge(entries);
            Modified = true;
            
            Notify(new EditorModelNotification
            {
                Type = EditorModelNotificationTypes.Replace,
                From = entries,
                To = new[] { mergedEntry }
            });            
        }

        public void Replace(IEnumerable<Entry> oldEntries, IEnumerable<Entry> newEntries)
        {
            _reader.Replace(oldEntries, newEntries);
            
            Modified = true;

            Notify(new EditorModelNotification
            {
                Type = EditorModelNotificationTypes.Replace,
                From = oldEntries,
                To = newEntries
            });
        }

        public void Reload()
        {
            Load(Path);

            Modified = false;
        }

        public System.Text.Encoding Encoding { get; set; }

        public IEnumerable<Entry> Entries
        {
            get
            {
                return _reader.Entries;
            }
        }

        public bool Empty
        {
            get { return Entries == null; }
        }

        public bool Modified
        {
            get
            {
                return _modified;
            }

            private set
            {
                _modified = value;

                Notify(new EditorModelNotification
                {
                    Type = EditorModelNotificationTypes.Modified,
                });
            }
        }
    }
}